package com.lgy.ms.service.service.business;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.lgy.ms.api.business.IAppFileService;
import com.lgy.ms.core.bean.RequestParams;
import com.lgy.ms.core.bean.ResponseParams;
import com.lgy.ms.core.dto.FileDTO;
import com.lgy.ms.core.enums.CommonEnum;
import com.lgy.ms.core.exception.BusinessException;
import com.lgy.ms.core.utils.SysHelper;
import com.lgy.ms.service.config.GlobalNames;
import com.lgy.ms.service.dao.FileDao;
import com.lgy.ms.service.service.base.AppBaseService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

@Service(value = "appFileService")
public class AppFileServiceImpl extends AppBaseService implements IAppFileService {

    @Resource
    private FileDao fileDao;

    @Override
    public ResponseParams<Object> add(RequestParams requestParams) throws BusinessException {
        ResponseParams<Object> response = buildResponseParams(requestParams);
        try {
            FileDTO fileDTO = super.paramToObject(requestParams, FileDTO.class);
            FileDTO record = fileDao.selectByParam(fileDTO);
            if (record != null) {
                record.setUrl(fileDTO.getUrl());
                record.setSize(fileDTO.getSize());
                record.setUploadDate(DatePattern.PURE_DATE_FORMAT.format(DateUtil.date()));
                fileDao.updateByPrimaryKeySelective(record);
            } else {
                fileDTO.setFileId(SysHelper.getUUID("PJ_", 32));
                fileDTO.setUploadDate(DatePattern.PURE_DATE_FORMAT.format(DateUtil.date()));
                fileDTO.setDeleted(CommonEnum.Normal.value);
                fileDao.insert(fileDTO);
            }
            return finish(response);
        } catch (Exception e) {
            throw super.processException(e, e.getMessage());
        }
    }

    @Override
    public ResponseParams<Object> edit(RequestParams requestParams) throws BusinessException {
        ResponseParams<Object> response = buildResponseParams(requestParams);
        try {
            FileDTO fileDTO = super.paramToObject(requestParams, FileDTO.class);
            fileDao.updateByPrimaryKeySelective(fileDTO);
            return finish(response);
        } catch (Exception e) {
            throw super.processException(e, e.getMessage());
        }
    }

    @Override
    public ResponseParams<Object> delete(RequestParams requestParams) throws BusinessException {
        ResponseParams<Object> response = buildResponseParams(requestParams);
        try {
            FileDTO fileDTO = super.paramToObject(requestParams, FileDTO.class);
            String[] ids = fileDTO.getFileId().split(",");
            if (ArrayUtil.isNotEmpty(ids)) {
                for (String id : ids) {
                    fileDao.deleteByPrimaryKey(id);
                }
            }
            return finish(response);
        } catch (Exception e) {
            throw super.processException(e, e.getMessage());
        }
    }

    @Override
    public ResponseParams<Object> queryByPage(RequestParams requestParams) throws BusinessException {
        try {
            FileDTO fileDTO = super.paramToObject(requestParams, FileDTO.class);
            List<FileDTO> list = fileDao.queryByPage(fileDTO);
            ResponseParams<Object> response = getPage(requestParams, list);
            return finish(response);
        } catch (Exception e) {
            throw super.processException(e, e.getMessage());
        }
    }

    @Override
    public ResponseParams<Object> zipByProject(RequestParams requestParams) throws BusinessException {
        ResponseParams<Object> response = buildResponseParams(requestParams);
        try {
            FileDTO fileDTO = super.paramToObject(requestParams, FileDTO.class);
            List<FileDTO> fileList = fileDao.selectByProjectId(fileDTO.getProjectId());
            List<File> files = Lists.newArrayList();
            if (CollUtil.isNotEmpty(fileList)) {
                for (FileDTO dto : fileList) {
                    files.add(FileUtil.file(changeHttp2file(dto.getUrl())));
                }
                response.setParam(zipFiles(files));
            } else {
                throw new BusinessException("此项目无附属文件");
            }
            return finish(response);
        } catch (Exception e) {
            throw super.processException(e, e.getMessage());
        }
    }

    private String changeHttp2file(String path) {
        return GlobalNames.download_zip_file_path + path.split(GlobalNames.file_path_split)[1];
    }

    private String zipFiles(List<File> files) throws BusinessException {
        String zipPath = "zipPath/" + DateUtil.today() + "/files" + DatePattern.PURE_TIME_FORMAT.format(DateUtil.date()) + ".zip";
        InputStream[] inputStreams = ArrayUtil.newArray(InputStream.class, files.size());
        String[] fileNames = ArrayUtil.newArray(String.class, files.size());
        if (CollUtil.isNotEmpty(files)) {
            for (int i = 0; i < files.size(); i++) {
                fileNames[i] = FileUtil.getName(files.get(i));
                inputStreams[i] = FileUtil.getInputStream(files.get(i));
            }
            try {
                ZipUtil.zip(FileUtil.file(GlobalNames.download_zip_file_path + zipPath), fileNames, inputStreams);
            } catch (UtilException e) {
                throw new BusinessException("压缩失败：" + e.getMessage());
            }
        }
        return GlobalNames.download_zip_urlPrefix + zipPath;
    }

    @Override
    public ResponseParams<Object> zipBySelect(RequestParams requestParams) throws BusinessException {
        ResponseParams<Object> response = buildResponseParams(requestParams);
        try {
            Map<String, Object> req = super.getRequestParamMap();
            String filePaths = (String) req.get("filePaths");
            List<File> files = Lists.newArrayList();
            if (StrUtil.isNotBlank(filePaths)) {
                String[] urls = filePaths.split(",");
                if (ArrayUtil.isNotEmpty(urls)) {
                    for (String url : urls) {
                        files.add(FileUtil.file(changeHttp2file(url)));
                    }
                    response.setParam(zipFiles(files));
                }
            } else {
                throw new BusinessException("请勾选需要打包的文件");
            }
            return finish(response);
        } catch (Exception e) {
            throw super.processException(e, e.getMessage());
        }
    }

    @Override
    public PageInfo<FileDTO> getFileList(Map<String, Object> reqMap) {
        startPage(reqMap);
        FileDTO fileDTO = BeanUtil.mapToBean(reqMap, FileDTO.class, false);
        List<FileDTO> list =  fileDao.queryByPage(fileDTO);
        return new PageInfo<>(list);
    }
}
